package c2.cross.business.rank.h;

import c2.cross.business.rank.CrossRankDao;
import c2.cross.business.rank.data.CrossGuildRankData;
import cate.game.rank.cross.CrossRankMessageModule;
import cate.game.rank.po.GuildRank;
import easy.java.dev.note.NoteField;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.annotation.Transient;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@Slf4j
public class GuildCrossRankHandler {
    /**
     * 保存数据库的最小间隔时间
     */
    private static final long SAVE_INTERVAL = 60000;
    @Getter
    private final int rankId;
    @NoteField("榜单")
    private CrossGuildRankData rankData;
    @NoteField("上次存储检测时间")
    private long lastSaveCheckTime;
    @Transient
    private final CrossRankDao dao;

    public GuildCrossRankHandler(int rankId, CrossRankDao dao) {
        this.rankId = rankId;
        this.dao = dao;
        rankData = this.dao.getGuild(getTag());
        if (rankData == null) {
            rankData = createSaveData();
        }
    }

    private String getTag() {
        return "guild_cross_rank";
    }

    protected CrossGuildRankData createSaveData() {
        CrossGuildRankData spo = new CrossGuildRankData();
        spo.setTag(getTag());
        return spo;
    }

    protected int getRankNum() {
        return 100;
    }

    public synchronized void record(CrossRankMessageModule.UpdateGuildRecord record) {
        GuildRank his = findRankByGuildUid(record.guildUid);
        if (his != null && record.snapshot != null) {
            his.owner = record.snapshot.copy();
        }
        List<GuildRank> list = tryGetRankList();
        // 是否已经上榜
        if (list.size() >= getRankNum()) {
            GuildRank last = list.get(list.size() - 1);
            if (failCompareToLastOne(last.power, last.level, record.power, record.level)) {
                // 没有进排行榜
                return;
            }
        }
        if (his != null) {
            // 已经在榜上了
            his.level = record.level;
            his.power = record.power;
            his.memberNum = record.memberNum;
            his.memberLimit = record.memberLimit;
            his.srvId = record.srvId;
            his.guildName = record.guildName;
        } else {
            // 之前没有上榜
            GuildRank e = new GuildRank(record.guildUid, record.srvId, record.guildName, record.snapshot, record.level, record.power, record.memberNum, record.memberLimit);
            if (list.size() >= getRankNum()) {
                // 如果排行榜已经满了，那就把最后一名给去掉
                list.remove(list.size() - 1);
            }
            list.add(e);
        }
        sort();
    }

    public void sort(){
        tryGetRankList().sort(Comparator.comparing(GuildRank::getPower)
                .thenComparing(GuildRank::getLevel)
                .reversed());
    }

    public int getRankIndex(String guildUid) {
        try {
            List<GuildRank> list = tryGetRankList();
            for (int i = 0; i < list.size(); i++) {
                GuildRank rank = list.get(i);
                if (StringUtils.equals(rank.guildUid, guildUid)) {
                    return i + 1;
                }
            }
            return -1;
        } catch (Exception e) {
            return -1;
        }
    }

    public GuildRank findRankByGuildUid(String guildUid) {
        try {
            for (GuildRank rank : tryGetRankList()) {
                if (StringUtils.equals(guildUid, rank.guildUid)) {
                    return rank;
                }
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

    public List<GuildRank> getRankList(int limit) {
        try {
            List<GuildRank> list = tryGetRankList();
            if (limit == 0 || list.size() <= limit) {
                return new ArrayList<>(list);
            }
            return new ArrayList<>(list.subList(0, limit));
        } catch (Exception e) {
            // nothing
        }
        return Collections.emptyList();
    }

    /**
     * 循环
     */
    public void tick() {
        long nowTime = System.currentTimeMillis();
        if (nowTime - lastSaveCheckTime >= SAVE_INTERVAL) {
            lastSaveCheckTime = nowTime;
            save();
        }
    }

    public void save() {
        try {
            dao.saveGuild(rankData);
        }catch (Exception e) {
            log.error("排行榜{}保存失败", rankData.getTag());
        }
    }

    /**
     * 尝试获取排行列表
     */
    protected List<GuildRank> tryGetRankList() {
        if (rankData.getList() == null) {
            rankData.setList(new ArrayList<>());
        }
        return rankData.getList();
    }

    protected boolean failCompareToLastOne(long lastValue, long lastExtraValue, long value, long extraValue){
        return lastValue > value || (lastValue == value && lastExtraValue >= extraValue);
    }
}
